package com.diandian.backend.dingding.data.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.diandian.backend.dingding.data.clients.MiddleClient;
import com.diandian.backend.dingding.data.clients.dto.OapiV2DepartmentListsubResponse;
import com.diandian.backend.dingding.data.dto.DingdingDeptTreeAddParamDTO;
import com.diandian.base.boot.starter.exception.DefaultException;
import com.diandian.base.boot.starter.response.BaseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class DingdingDeptTreeSyncService {

    private static final Logger logger = LoggerFactory.getLogger(DingdingDeptTreeSyncService.class);

    @Autowired
    private DingdingDeptTreeService dingdingDeptTreeService;

    @Autowired
    private MiddleClient middleClient;

    @Value("${middle.appKey}")
    private String middleAppKey;

    @Value("${middle.appSecret}")
    private String middleAppSecret;

    @Transactional(rollbackFor = Exception.class)
    public void pull(String belong, String appKey, String appSecret, String rootDeptName) {

        if(belong == null || "".equals(belong)) {
            throw new DefaultException("归属标识不能为空");
        }
        if(appKey == null || "".equals(appKey) || appSecret == null || "".equals(appSecret)) {
            throw new DefaultException("密钥信息缺失");
        }

        // 定义初始值
        Long deptId = 1L;
        int deptLevel = 1;
        String deptPath = String.valueOf(deptId);

        // 清理历史数据
        dingdingDeptTreeService.deleteByBelong(belong);

        // 处理根节点
        rootDeptName = rootDeptName == null ? "根组织" : rootDeptName;
        saveRootDept(belong, deptId, deptLevel, rootDeptName);

        queryAndSaveDept(belong, appKey, appSecret, deptId, deptLevel, deptPath);

        logger.info("执行钉钉部门数据拉取完成。");
    }

    /**
     * 保存根组织
     */
    private void saveRootDept(String belong, Long deptId, int level, String deptName){
        DingdingDeptTreeAddParamDTO data = new DingdingDeptTreeAddParamDTO();
        data.setDeptCode(String.valueOf(deptId));
        data.setDeptName(deptName);
        data.setDeptPath(String.valueOf(deptId));
        data.setDeptLevel(level);
        data.setDeptNodeCode("0");
        data.setBelong(belong);
        dingdingDeptTreeService.add(data);
    }


    /**
     * 执行二级以下组织数据处理: 查询下级组织信息 - 保存下级组织 - 返回下级组织信息
     * @param belong
     * @param appKey
     * @param appSecret
     * @param parentDeptId 当前组织ID
     * @param parentLevel 当前组织登记
     * @param parentDeptPath 当前组织路径
     * @return
     */
    private void queryAndSaveDept(String belong, String appKey, String appSecret, Long parentDeptId, int parentLevel, String parentDeptPath) {
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptList = queryDeptList(appKey, appSecret, parentDeptId);
        batchSaveDept(belong, deptList, parentLevel + 1, parentDeptPath);

        if(deptList == null || deptList.size() == 0) {
            return;
        }

        for (int i = 0; i < deptList.size(); i++) {
            Long nextDeptId = deptList.get(i).getDeptId();
            int nextLevel = parentLevel + 1;
            queryAndSaveDept(belong, appKey, appSecret, nextDeptId, nextLevel, parentDeptPath + "." + nextDeptId);
        }
    }


    /**
     * 获取组织的直接下级组织
     */
    private List<OapiV2DepartmentListsubResponse.DeptBaseResponse> queryDeptList(String appKey, String appSecret, Long deptId) {

        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> resultList = null;

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("dingDeptId", deptId);
        jsonObject.put("language", "zh_CN");
        BaseResult baseResult = middleClient.getDeptList(middleAppKey, middleAppSecret, "dingding.exchange.dept.get.list", jsonObject);
        if(baseResult != null && baseResult.getCode() == 0) {
            OapiV2DepartmentListsubResponse response = JSON.parseObject(JSON.toJSONString(baseResult.getData()), OapiV2DepartmentListsubResponse.class);

            if(response != null && response.getErrcode() == 0 && response.getResult() != null && response.getResult().size() > 0) {
                resultList =  response.getResult();
            }
        }

        return resultList;
    }

    /**
     * 批量保存组织
     */
    private void batchSaveDept(String belong, List<OapiV2DepartmentListsubResponse.DeptBaseResponse> dataList, Integer itemDeptLevel, String parentDeptPath) {

        if(dataList == null || dataList.size() == 0) {
            return;
        }

        List<DingdingDeptTreeAddParamDTO> saveList = new ArrayList<>();
        for (OapiV2DepartmentListsubResponse.DeptBaseResponse deptResponse : dataList) {

            String itemDeptName = deptResponse.getName();
            String itemDeptCode = String.valueOf(deptResponse.getDeptId());
            String itemParentDeptCode = String.valueOf(deptResponse.getParentId());
            String itemDeptPath = (parentDeptPath == null || "".equals(parentDeptPath))? itemDeptCode : parentDeptPath + "." + itemDeptCode;

            DingdingDeptTreeAddParamDTO item = new DingdingDeptTreeAddParamDTO();
            item.setDeptCode(itemDeptCode);
            item.setDeptName(itemDeptName);
            item.setDeptPath(itemDeptPath);
            item.setDeptLevel(itemDeptLevel);
            item.setDeptNodeCode(itemParentDeptCode);
            item.setBelong(belong);
            saveList.add(item);
        }

        dingdingDeptTreeService.batchAdd(saveList);
    }
}
